﻿/**
 * describe:Analytic class
 * date:2022-09-06
 * author:lenny
 */
using Jt808DataParser.Enum;
using Jt808DataParser.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jt808DataParser.Utils
{
    public class PacketUtil
    {
        public static byte[] decodePacket(byte[] bytes)
        {
            //Find message trailer
            byte[] msgBodyNoHeader = bytes.Skip(1).Take(bytes.Length - 1).ToArray();
            int tailIndex = CommonUtil.BytesIndexOf(msgBodyNoHeader, 0x7E);
            if (tailIndex <= 0)
            {
                return null;
            }
            return CommonUtil.unescape(bytes, tailIndex).ToArray();
        }

        /// <summary>
        /// Parse and locate the message body
        /// </summary>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        public static LocationData parseLocationBody(byte[] msgBodyBuf)
        {
            //Alarm sign
            long alarmFlag = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 0));
            //status
            long status = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 4));
            //latitude
            double lat = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 8)) * 0.000001;
            //longitude
            double lon = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 12)) * 0.000001;
            //Altitude, in meters
            int altitude = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 16));
            //speed
            double speed = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 18)) * 0.1;
            //direction
            int direction = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 20));
            //gps time
            DateTime gpsDateTime = CommonUtil.GetDataTime(msgBodyBuf.Skip(22).Take(6).ToArray());
            //Judge whether south latitude and west longitude
            if (CommonUtil.getBitValue(status, 2) == 1)
            {
                lat = -lat;
            }
            if (CommonUtil.getBitValue(status, 3) == 1)
            {
                lon = -lon;
            }
            //Positioning type
            int locationType = CommonUtil.getBitValue(status, 1);
            //ACC
            int acc = CommonUtil.getBitValue(status, 0);

            List<int> alarmTypeList = parseAlarm(alarmFlag);
            LocationData locationData = new LocationData();
            locationData.GpsTime = gpsDateTime.ToString("yyyy-MM-dd HH:mm:ss");
            locationData.Latitude = lat;
            locationData.Longitude = lon;
            locationData.LocationType = locationType;
            locationData.Speed = (int)speed;
            locationData.Direction = direction;
            locationData.Altitude = altitude;
            locationData.ACC = acc;
            locationData.AlarmTypeList = alarmTypeList;
            //Expand information analysis
            if (msgBodyBuf.Length > 28)
            {
                byte[] extraBytes = msgBodyBuf.Skip(28).Take(msgBodyBuf.Length - 28).ToArray();
                parseExtraInfo(extraBytes, locationData);
            }
            return locationData;
        }

        /// <summary>
        /// Parse alarm
        /// </summary>
        /// <param name="alarmFlag"></param>
        /// <returns></returns>
        private static List<int> parseAlarm(long alarmFlag)
        {
            List<int> alarmTypeList = new List<int>();
            for (int i = 0; i < 32; i++)
            {
                if (CommonUtil.getBitValue(alarmFlag, i) == 1)
                {
                    try
                    {
                        alarmTypeList.Add(i);
                    }
                    catch (Exception e) { }
                }
            }
            return alarmTypeList;
        }

        /// <summary>
        /// Parse additional information
        /// </summary>
        /// <param name="msgBody"></param>
        /// <param name="location"></param>
        private static void parseExtraInfo(byte[] msgBody, LocationData location)
        {
            byte[] extraInfoBuf = null;
            Dictionary<string, Object> extraInfo = new Dictionary<string, object>();
            while (msgBody.Length > 1)
            {
                int extraInfoId = msgBody[0];
                int extraInfoLen = msgBody[1];
                if (msgBody.Length - 2 < extraInfoLen)
                {
                    break;
                }
                extraInfoBuf = msgBody.Skip(2).Take(extraInfoLen).ToArray();
                msgBody = msgBody.Skip(2 + extraInfoLen).Take(msgBody.Length - (2 + extraInfoLen)).ToArray();
                switch (extraInfoId)
                {
                    //mileage
                    case 0x01:
                        double mileage = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0)) * 0.1;
                        location.Mileage = (long)mileage;
                        break;
                    //Signal strength of wireless communication network
                    case 0x30:
                        int fCellSignal = extraInfoBuf[0];
                        location.GSMSignal = fCellSignal;
                        break;
                    //Number of satellites
                    case 0x31:
                        int fGPSSignal = extraInfoBuf[0];
                        location.GpsSignal = fGPSSignal;
                        break;
                    case 0xF0:
                        try
                        {
                            List<string> cells = new List<string>();
                            while (extraInfoBuf.Length > 11)
                            {
                                if (extraInfoBuf.Length % 12 == 0)
                                {
                                    //MCC
                                    int mcc = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                                    //MNC
                                    int mnc = extraInfoBuf[2];
                                    //ci
                                    long ci = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 3));
                                    //lac
                                    long lac = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 7));
                                    //signal intensity
                                    int rssi = (sbyte)extraInfoBuf[11];
                                    cells.Add(string.Format("{0},{1},{2},{3},{4}", mcc, mnc, lac, ci, rssi));
                                    extraInfoBuf = extraInfoBuf.Skip(12).Take(extraInfoBuf.Length - 12).ToArray();
                                }
                                else
                                {
                                    //MCC
                                    int mcc = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                                    //MNC
                                    int mnc = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 2));
                                    //ci
                                    long ci = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 4));
                                    //lac
                                    long lac = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 8));
                                    //signal intensity
                                    int rssi = (sbyte)extraInfoBuf[12];
                                    cells.Add(string.Format("{0},{1},{2},{3},{4}", mcc, mnc, lac, ci, rssi));
                                    extraInfoBuf = extraInfoBuf.Skip(13).Take(extraInfoBuf.Length - 13).ToArray();
                                }
                            }
                            if (cells.Count > 0) {
                                extraInfo.Add("Cells",  cells);
                            }
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF1:
                        long voltageF1 = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0));
                        extraInfo.Add("ExternalVoltage", double.Parse((voltageF1 * 0.001).ToString("F")));
                        break;
                    case 0xF2:
                        extraInfo.Add("SoftwareVersion", CommonUtil.ByteToASCII(extraInfoBuf));
                        break;
                    case 0xF3:
                        try
                        {
                            //Shielded word
                            int maskF2 = extraInfoBuf[0];
                            extraInfoBuf = extraInfoBuf.Skip(1).Take(extraInfoBuf.Length - 1).ToArray();
                            List<Dictionary<string, object>> bluetoothList = new List<Dictionary<string, object>>();
                            while (extraInfoBuf.Length > 7)
                            {
                                Dictionary<string, object> bleMap = new Dictionary<string, object>();
                                byte[] macArr = extraInfoBuf.Skip(0).Take(6).ToArray();
                                bleMap.Add("Bluetooth_Mac", CommonUtil.ByteToHexStr(macArr));
                                bleMap.Add("Bluetooth_Rssi", (sbyte)extraInfoBuf[6]);
                                extraInfoBuf = extraInfoBuf.Skip(7).Take(extraInfoBuf.Length - 7).ToArray();
                                if ((maskF2 & 0x01) > 0)
                                {
                                    byte[] nameArr = extraInfoBuf.Skip(0).Take(10).ToArray();
                                    extraInfoBuf = extraInfoBuf.Skip(10).Take(extraInfoBuf.Length - 10).ToArray();
                                    bleMap.Add("Bluetooth_Name", CommonUtil.ByteToASCII(nameArr));
                                }
                                if ((maskF2 & 0x02) > 0)
                                {
                                    bleMap.Add("Bluetooth_FwVer", CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                                if ((maskF2 & 0x04) > 0)
                                {
                                    bleMap.Add("Bluetooth_Voltage", double.Parse((CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)) * 0.001).ToString("F")));
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                                if ((maskF2 & 0x08) > 0)
                                {
                                    bleMap.Add("Bluetooth_Temperature", parseTemperature(CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0))));
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                                if ((maskF2 & 0x10) > 0)
                                {
                                    bleMap.Add("Bluetooth_Humidity", double.Parse((CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)) * 0.1).ToString("0.0")));
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                                if ((maskF2 & 0x20) > 0)
                                {
                                    int x = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                                    int y = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 2));
                                    int z = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 4));
                                    x = x > 32768 ? (x - 65536) : x;
                                    y = y > 32768 ? (y - 65536) : y;
                                    z = z > 32768 ? (z - 65536) : z;
                                    bleMap.Add("Bluetooth_Sensor", string.Format("x:{0},y:{1},z:{2}", x, y, z));
                                    extraInfoBuf = extraInfoBuf.Skip(6).Take(extraInfoBuf.Length - 6).ToArray();
                                }
                                if ((maskF2 & 0x40) > 0)
                                {
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                                if ((maskF2 & 0x80) > 0)
                                {
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                                bluetoothList.Add(bleMap);
                            }
                            extraInfo.Add("Bluetooth", bluetoothList);
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF4:
                        try
                        {
                            //WIFI infomation
                            List<Dictionary<string, object>> wifiList = new List<Dictionary<string, object>>();
                            while (extraInfoBuf.Length >= 0x07)
                            {
                                Dictionary<string, object> wifiMap = new Dictionary<string, object>();
                                byte[] wifiMacArr = extraInfoBuf.Skip(0).Take(6).ToArray();
                                wifiMap.Add("WIFI_Mac", CommonUtil.ByteToHexStr(wifiMacArr));
                                wifiMap.Add("WIFI_Rssi", (sbyte)extraInfoBuf[6]);
                                extraInfoBuf = extraInfoBuf.Skip(7).Take(extraInfoBuf.Length - 7).ToArray();
                                wifiList.Add(wifiMap);
                            }
                            extraInfo.Add("WIFI", wifiList);
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF5:
                        try
                        {
                            if (extraInfoBuf.Length > 0x07)
                            {
                                if (CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 4)) == 0)
                                {
                                    List<int> alarmTypeList = location.AlarmTypeList;
                                    alarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_1);
                                    location.AlarmTypeList = alarmTypeList;
                                }
                            }
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF6:
                        try
                        {
                            //Sensors infomation
                            Dictionary<string,object> sensorInfo=new Dictionary<string, object>();
                            int dataType = extraInfoBuf[0];
                            sensorInfo.Add("Sensor_DataType", dataType);
                            int maskF6 = extraInfoBuf[1];
                            extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                            switch (dataType)
                            {
                                case 1:
                                case 0x60:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_5);
                                    break;
                                case 3:
                                case 0x53:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ALARM_29);
                                    break;
                                case 4:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_2);
                                    break;
                                case 5:
                                case 6:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_3);
                                    break;
                                case 7:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_4);
                                    break;
                                case 0x0D:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_16);
                                    break;
                                case 0x0F:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_17);
                                    break;
                                case 0x4A:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ALARM_1);
                                    break;
                                case 0x4F:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ALARM_7);
                                    break;
                                case 0x51:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_11);
                                    break;
                                case 0x54:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_6);
                                    break;
                                case 0x6C:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_7);
                                    break;
                                case 0x6D:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_8);
                                    break;
                                case 0x6E:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_9);
                                    break;
                                case 0x6F:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_10);
                                    break;
                                case 0x71:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_12);
                                    break;
                                case 0x74:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_13);
                                    break;
                                case 0x75:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_14);
                                    break;
                                case 0x76:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ALARM_19);
                                    break;
                                case 0x77:
                                    location.AlarmTypeList.Add((int)AlarmTypeEnum.ExtraALARM_15);
                                    break;
                                default:
                                    break;
                            }
                            sensorInfo.Add("Sensor_List", parseSensorListInfo(maskF6, extraInfoBuf));

                            extraInfo.Add("Sensor", sensorInfo);
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF7:
                        try
                        {
                            Dictionary<string, object> batteryInfo = new Dictionary<string, object>();
                            long aovx_voltage = CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0));
                            batteryInfo.Add("Battery_Voltage", double.Parse((aovx_voltage * 0.001).ToString("F")));
                            if (extraInfoBuf.Length > 5)
                            {
                                int chargeStatus = extraInfoBuf[4];
                                batteryInfo.Add("Battery_ChargeStatus", chargeStatus);
                                int batteryF7 = extraInfoBuf[5];
                                batteryInfo.Add("Battery_Level", batteryF7);
                            }
                            extraInfo.Add("Battery", batteryInfo);
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF8:
                        try
                        {
                            if (extraInfoBuf.Length >= 0x1B)
                            {
                                Dictionary<string, object> deviceInfo = new Dictionary<string, object>();
                                int aovx_workModel = extraInfoBuf[0];
                                deviceInfo.Add("Device_WorkModel", aovx_workModel);
                                byte[] aovx_imeiArr = extraInfoBuf.Skip(1).Take(8).ToArray();
                                deviceInfo.Add("Device_IMEI", CommonUtil.ByteToHexStr(aovx_imeiArr));
                                byte[] aovx_iccidArr = extraInfoBuf.Skip(9).Take(10).ToArray();
                                deviceInfo.Add("Device_ICCID", CommonUtil.ByteToHexStr(aovx_iccidArr));
                                byte[] aovx_deviceTypeArr = extraInfoBuf.Skip(19).Take(10).ToArray();
                                deviceInfo.Add("Device_Type", CommonUtil.ByteToASCII(aovx_deviceTypeArr));
                                extraInfo.Add("Device", deviceInfo);
                            }
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xF9:
                        try
                        {
                            //Auxiliary Information
                            Dictionary<string, object> auxiliaryInfo = new Dictionary<string, object>();
                            int maskF9 = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                            extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                            if ((maskF9 & 0x01) > 0)
                            {
                                auxiliaryInfo.Add("Position_Age", CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0)));
                                extraInfoBuf = extraInfoBuf.Skip(4).Take(extraInfoBuf.Length - 4).ToArray();
                            }
                            if ((maskF9 & 0x02) > 0)
                            {
                                auxiliaryInfo.Add("Acc_Duration", CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0)));
                                extraInfoBuf = extraInfoBuf.Skip(4).Take(extraInfoBuf.Length - 4).ToArray();
                            }
                            if ((maskF9 & 0x04) > 0)
                            {
                                auxiliaryInfo.Add("HDOP", CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                                extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                            }
                            if ((maskF9 & 0x08) > 0)
                            {
                                byte[] gnssTimeArr = extraInfoBuf.Skip(0).Take(6).ToArray();
                                auxiliaryInfo.Add("Gnss_Time", CommonUtil.GetDataTime(gnssTimeArr).ToString("yyyy-MM-dd HH:mm:ss"));
                                extraInfoBuf = extraInfoBuf.Skip(6).Take(extraInfoBuf.Length - 6).ToArray();
                            }
                            //20240112 Apollo customized data
                            if ((maskF9 & 0x10) > 0) {
                                byte[] apolloArr = extraInfoBuf.Skip(0).Take(18).ToArray();
                                extraInfoBuf = extraInfoBuf.Skip(18).Take(extraInfoBuf.Length - 18).ToArray();
                            }
                            //20240112
                            if ((maskF9 & 0x20) > 0)
                            {
                                auxiliaryInfo.Add("Sample_Time", CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0)));
                                auxiliaryInfo.Add("Report_Time", CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 4)));
                                extraInfoBuf = extraInfoBuf.Skip(8).Take(extraInfoBuf.Length - 8).ToArray();
                            }
                            //20240112
                            if ((maskF9 & 0x40) > 0) {
                                int maskExtTemp = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                                extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                if ((maskExtTemp & 0x01)>0)
                                {
                                    //temperature
                                    double ext_temp = parseTemperature(CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                                    auxiliaryInfo.Add("Ext_Temp", ext_temp);
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                    double ext_temp_max = parseTemperature2(CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                                    auxiliaryInfo.Add("Ext_Temp_Max", ext_temp_max);
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                    double ext_temp_min = parseTemperature2(CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                                    auxiliaryInfo.Add("Ext_Temp_min", ext_temp_min);
                                    extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                                }
                            }
                            extraInfo.Add("Auxiliary", auxiliaryInfo);
                        }
                        catch (Exception ex) { }
                        break;
                    case 0xFA:
                        try
                        {
                            Dictionary<string, object> meterMap = new Dictionary<string, object>();
                            meterMap.Add("Power", CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                            extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                            meterMap.Add("Total_Electricity", CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0)));
                            extraInfoBuf = extraInfoBuf.Skip(4).Take(extraInfoBuf.Length - 4).ToArray();
                            meterMap.Add("Remaining_Electricity", CommonUtil.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0)));
                            extraInfoBuf = extraInfoBuf.Skip(4).Take(extraInfoBuf.Length - 4).ToArray();
                            meterMap.Add("Purchase_Times", CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                            extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                            meterMap.Add("Status", parseMeterStatus(CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0))));
                            extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                            extraInfo.Add("Meter", meterMap);
                        }
                        catch (Exception e) { }
                        break;
                    default:
                        break;
                }
            }
            location.ExtraInfoMap = extraInfo;
        }

        /// <summary>
        /// parse 0xF6
        /// </summary>
        /// <param name="maskF6"></param>
        /// <param name="extraInfoBuf"></param>
        /// <returns></returns>
        private static List<object> parseSensorListInfo(int maskF6,byte[] extraInfoBuf)
        {
            try
            {
                List<object> sensorList = new List<object>();

                while (extraInfoBuf.Length > 1)
                {
                    Dictionary<string, object> sensorInfo = new Dictionary<string, object>();
                    if ((maskF6 & 0x01) > 0)
                    {
                        //Illuminance
                        int aovx_light = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                        sensorInfo.Add("Sensor_Light", aovx_light);
                    }
                    if ((maskF6 & 0x02) > 0)
                    {
                        //temperature
                        double aovx_temperature = parseTemperature(CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0)));
                        extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                        sensorInfo.Add("Sensor_Temperature", aovx_temperature);
                    }

                    if ((maskF6 & 0x04) > 0)
                    {
                        //humidity
                        int aovx_humidity = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                        sensorInfo.Add("Sensor_Humidity", double.Parse((aovx_humidity * 0.1).ToString("0.0")));
                    }
                    if ((maskF6 & 0x08) > 0)
                    {
                        //Accelerometer
                        int x = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        int y = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 2));
                        int z = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 4));
                        x = x > 32768 ? (x - 65536) : x;
                        y = y > 32768 ? (y - 65536) : y;
                        z = z > 32768 ? (z - 65536) : z;
                        extraInfoBuf = extraInfoBuf.Skip(6).Take(extraInfoBuf.Length - 6).ToArray();
                        sensorInfo.Add("Sensor_Accelerometer", string.Format("x:{0},y:{1},z:{2}", x, y, z));
                    }

                    if ((maskF6 & 0x10) > 0)
                    {
                        //Alarm information
                        int light_Limit = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        int temp_Max = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 2));
                        int temp_Min = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 4));
                        int hum_Max = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 6));
                        int hum_Min = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 8));
                        sensorInfo.Add("Light_Limit", light_Limit);
                        sensorInfo.Add("Temperature_Max", parseTemperature2(temp_Max));
                        sensorInfo.Add("Temperature_Min", parseTemperature2(temp_Min));
                        sensorInfo.Add("Humidity_Max", double.Parse((hum_Max * 0.1).ToString("0.0")));
                        sensorInfo.Add("Humidity_Min", double.Parse((hum_Min * 0.1).ToString("0.0")));
                        extraInfoBuf = extraInfoBuf.Skip(10).Take(extraInfoBuf.Length - 10).ToArray();
                        //if (sensorInfo.ContainsKey("Sensor_Light"))
                        //{
                        //    int aovx_light = (int)sensorInfo["Sensor_Light"];
                        //    //Judge light alarm
                        //    AlarmDescribe describe = new AlarmDescribe();
                        //    describe.T = 5;
                        //    describe.N = aovx_light.ToString();
                        //    describe.F = light_Limit.ToString();
                        //    sensorInfo.Add("Sensor_LightAlarmDescribe", JsonConvert.SerializeObject(describe));
                        //}
                        //if (sensorInfo.ContainsKey("Sensor_Temperature"))
                        //{
                        //    double aovx_temperature = (double)sensorInfo["Sensor_Temperature"];
                        //    //Judge temperature alarm
                        //    if ((maskF6 & 0x02) > 0 && (aovx_temperature > temp_Max || aovx_temperature < temp_Min))
                        //    {
                        //        AlarmDescribe describe = new AlarmDescribe();
                        //        if (aovx_temperature > temp_Max)
                        //        {
                        //            describe.T = 1;
                        //            describe.N = aovx_temperature.ToString();
                        //            describe.F = temp_Max.ToString();
                        //        }
                        //        else
                        //        {
                        //            describe.T = 2;
                        //            describe.N = aovx_temperature.ToString();
                        //            describe.F = temp_Min.ToString();
                        //        }
                        //        sensorInfo.Add("Sensor_TempAlarmDescribe", JsonConvert.SerializeObject(describe));
                        //    }
                        //}

                        //if (sensorInfo.ContainsKey("Sensor_Humidity"))
                        //{
                        //    double aovx_humidity = (double)sensorInfo["Sensor_Humidity"];
                        //    //Judge humidity alarm
                        //    if ((maskF6 & 0x04) > 0 && (aovx_humidity > hum_Max || aovx_humidity < hum_Min))
                        //    {
                        //        AlarmDescribe describe = new AlarmDescribe();
                        //        if (aovx_humidity > hum_Max)
                        //        {
                        //            describe.T = 3;
                        //            describe.N = aovx_humidity.ToString();
                        //            describe.F = hum_Max.ToString();
                        //        }
                        //        else
                        //        {
                        //            describe.T = 4;
                        //            describe.N = aovx_humidity.ToString();
                        //            describe.F = hum_Min.ToString();
                        //        }
                        //        sensorInfo.Add("Sensor_HumAlarmDescribe", JsonConvert.SerializeObject(describe));
                        //    }
                        //}
                    }

                    //pressure
                    if ((maskF6 & 0x20) > 0)
                    {
                        int pressure = CommonUtil.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0))*100;
                        sensorInfo.Add("Pressure", pressure);
                        extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                    }
                    //Res2
                    if ((maskF6 & 0x40) > 0)
                    {
                        extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                    }
                    //Res3
                    if ((maskF6 & 0x80) > 0)
                    {
                        extraInfoBuf = extraInfoBuf.Skip(2).Take(extraInfoBuf.Length - 2).ToArray();
                    }
                    sensorList.Add(sensorInfo);
                }
                return sensorList;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        /// <summary>
        /// 电表状态集合
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        private static List<int> parseMeterStatus(int status)
        {
            List<int> meterStatus = new List<int>();
            for (int i = 0; i < 7; i++)
            {
                meterStatus.Add(CommonUtil.getBitValue(status, i));
            }
            return meterStatus;
        }

        /// <summary>
        /// Temperature analysis
        /// </summary>
        /// <param name="temperatureInt"></param>
        /// <returns></returns>
        private static double parseTemperature(int temperatureInt)
        {
            double temperature = Convert.ToInt16(temperatureInt.ToString("x2"), 16) * 0.1;
            return double.Parse(temperature.ToString("0.0"));
        }

        /// <summary>
        /// Temperature analysis
        /// </summary>
        /// <param name="temperatureInt"></param>
        /// <returns></returns>
        private static double parseTemperature2(int temperatureInt)
        {
            double temperature = Convert.ToInt16(temperatureInt.ToString("x2"), 16);
            return double.Parse(temperature.ToString("0.0"));
        }

        /// <summary>
        /// General response
        /// </summary>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        public static GeneralResponse parseGeneralResponse(byte[] msgBodyBuf)
        {
            //Response serial number
            int replyMsgFlowId = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
            //Response message ID
            int replyMsgId = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 2));
            //Results (0: success/confirmation; 1: failure; 2: message error; 3: not supported)
            int result = msgBodyBuf[4];
            GeneralResponse generalResponse = new GeneralResponse();
            generalResponse.ResponseSequence = replyMsgFlowId;
            generalResponse.ResponseID = CommonUtil.formatMessageId(replyMsgId);
            generalResponse.Result = result;
            return generalResponse;
        }

        /// <summary>
        /// Analyze vehicle registration information
        /// </summary>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        public static DeviceRegistration parseDeviceRegistration(byte[] msgBodyBuf)
        {
            DeviceRegistration registerInfo = new DeviceRegistration();
            //Province Id
            registerInfo.ProvinceId = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
            //City Id
            registerInfo.CityId = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 2));
            //Producer Id
            byte[] producerArr = msgBodyBuf.Skip(4).Take(5).ToArray();
            registerInfo.ProducerId = CommonUtil.ByteToASCII(producerArr);
            //Device type
            byte[] deviceTypeArr = msgBodyBuf.Skip(9).Take(20).ToArray();
            registerInfo.DeviceType = CommonUtil.ByteToASCII(deviceTypeArr);
            //Device ID
            byte[] deviceIDArr = msgBodyBuf.Skip(29).Take(7).ToArray();
            registerInfo.DeviceID = CommonUtil.ByteToASCII(deviceIDArr);
            //License plate color
            registerInfo.LicensePlateColor = msgBodyBuf[36];
            //Vehicle No.
            byte[] vehicleNoArr = msgBodyBuf.Skip(37).Take(msgBodyBuf.Length - 37).ToArray();
            registerInfo.VehicleNo = CommonUtil.ByteToASCII(vehicleNoArr);
            return registerInfo;
        }

        /// <summary>
        /// Query device response
        /// </summary>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        public static DeviceParameter parseDeviceParameter(byte[] msgBodyBuf)
        {
            try
            {
                DeviceParameter deviceParameter = new DeviceParameter();
                //Response serial number
                int replyMsgFlowId = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
                //Number of response parameters
                int itemCount = msgBodyBuf[2];
                //Parameter item data
                byte[] itemContentBuf = msgBodyBuf.Skip(3).Take(msgBodyBuf.Length - 3).ToArray();
                Dictionary<string, object> itemMap = new Dictionary<string, object>();
                while (itemContentBuf.Length > 1)
                {
                    try
                    {
                        long parameterID = CommonUtil.SwapUInt32(BitConverter.ToUInt32(itemContentBuf, 0));
                        int parameterLen = itemContentBuf[4];
                        if (itemContentBuf.Length - 5 < parameterLen)
                        {
                            break;
                        }
                        byte[] parameterArr = itemContentBuf.Skip(5).Take(parameterLen).ToArray();
                        object paramValue = null;
                        itemContentBuf = itemContentBuf.Skip(5 + parameterLen).Take(itemContentBuf.Length - (5 + parameterLen)).ToArray();
                        switch (parameterID)
                        {
                            //int32
                            case 0x0001:
                            case 0x0018:
                            case 0x0019:
                            case 0x001B:
                            case 0x001C:
                            case 0x0020:
                            case 0x0021:
                            case 0x0022:
                            case 0x0027:
                            case 0x0028:
                            case 0x0029:
                            case 0x002C:
                            case 0x002D:
                            case 0x002E:
                            case 0x002F:
                            case 0x0030:
                            case 0x0045:
                            case 0x0046:
                            case 0x0047:
                            case 0x0050:
                            case 0x0051:
                            case 0x0052:
                            case 0x0053:
                            case 0x0054:
                            case 0x0055:
                            case 0x0056:
                            case 0x0057:
                            case 0x0058:
                            case 0x0059:
                            case 0x005A:
                            case 0x0064:
                            case 0x0065:
                            case 0x0070:
                            case 0x0071:
                            case 0x0072:
                            case 0x0073:
                            case 0x0074:
                            case 0x0080:
                            case 0x0093:
                            case 0x0095:
                            case 0x0100:
                            case 0x0102:
                                paramValue = BitConverter.ToInt32(parameterArr, 0);
                                break;
                            //string
                            case 0x0010:
                            case 0x001A:
                            case 0x001D:
                            case 0x0040:
                            case 0x0041:
                            case 0x0042:
                            case 0x0043:
                            case 0x0044:
                            case 0x0048:
                            case 0x0049:
                            case 0x0083:
                                paramValue = CommonUtil.ByteToASCII(parameterArr);
                                break;
                            //int16
                            case 0x0031:
                            case 0x005B:
                            case 0x005C:
                            case 0x005D:
                            case 0x005E:
                            case 0x0081:
                            case 0x0082:
                            case 0x0101:
                            case 0x0103:
                                paramValue = BitConverter.ToInt16(parameterArr, 0);
                                break;
                            //int8
                            case 0x0084:
                            case 0x0090:
                            case 0x0091:
                            case 0x0092:
                            case 0x0094:
                                paramValue = parameterArr[0];
                                break;
                            default:
                                paramValue = CommonUtil.ByteToHexStr(parameterArr);
                                break;

                        }
                        itemMap.Add(CommonUtil.formatLongToHex(parameterID), paramValue);
                    }
                    catch (Exception e) { }
                }
                deviceParameter.ReplyMsgFlowId = replyMsgFlowId;
                deviceParameter.ItemCount = itemCount;
                deviceParameter.ItemMap = itemMap;
                return deviceParameter;
            }
            catch (Exception e) {
                return null;
            }
        }

        /// <summary>
        /// Transparent data processing
        /// </summary>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        public static TransparentMessage parseTransparentMessage(byte[] msgBodyBuf)
        {
            TransparentMessage transparentMessage = new TransparentMessage();
            //Transparent message type
            int msgType = msgBodyBuf[0];
            if (msgBodyBuf.Length > 1)
            {
                byte[] msgContentArr = msgBodyBuf.Skip(1).Take(msgBodyBuf.Length - 1).ToArray();
                transparentMessage.MsgType = msgType;
                switch (msgType) {
                    case 0x41:
                    case 0x42:
                        transparentMessage.MsgContent = CommonUtil.ByteToASCII(msgContentArr);
                        break;
                    case 0x51:
                        transparentMessage.MsgContent = parse51TransparentMessage(msgContentArr);
                        break;
                    case 0x52:
                        transparentMessage.MsgContent = parse52TransparentMessage(msgContentArr);
                        break;
                    case 0x54:
                        transparentMessage.MsgContent = parse54TransparentMessage(msgContentArr);
                        break;
                    default:
                        transparentMessage.MsgContent = "";
                        break;
                }
                return transparentMessage;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// BLE MOKO M2
        /// </summary>
        /// <param name="msgContentArr"></param>
        /// <returns></returns>
        private static string parse51TransparentMessage(byte[] msgContentArr) {
            try
            {
                Dictionary<string, object> m2Map = new Dictionary<string, object>();
                //mac (6 byte)
                byte[] macArr = msgContentArr.Skip(0).Take(6).ToArray();
                m2Map.Add("Mac", CommonUtil.ByteToHexStr(macArr));
                msgContentArr = msgContentArr.Skip(6).Take(msgContentArr.Length - 6).ToArray();
                //m2 total status quantity (1 byte)
                m2Map.Add("Total_Status", (sbyte)msgContentArr[0]);
                msgContentArr = msgContentArr.Skip(1).Take(msgContentArr.Length - 1).ToArray();
                //Current status data
                byte[] currentStatus = msgContentArr.Skip(0).Take(6).ToArray();
                //Decoding current status data
                m2Map.Add("Current_Status", CommonUtil.ByteToHexStr(currentStatus));
                msgContentArr = msgContentArr.Skip(6).Take(msgContentArr.Length - 6).ToArray();
                //Historical status data
                List<string> historicalStatusList = new List<string>();
                while (msgContentArr.Length >= 6) {
                    byte[] historicalStatus = msgContentArr.Skip(0).Take(6).ToArray();
                    //Decoding historical status data
                    historicalStatusList.Add(CommonUtil.ByteToHexStr(historicalStatus));
                    msgContentArr = msgContentArr.Skip(6).Take(msgContentArr.Length - 6).ToArray();
                }
                m2Map.Add("Historical_Status", historicalStatusList);
                return JsonConvert.SerializeObject(m2Map);
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// BLE Eddystone
        /// </summary>
        /// <param name="msgContentArr"></param>
        /// <returns></returns>
        private static string parse52TransparentMessage(byte[] msgContentArr)
        {
            try
            {
                Dictionary<string, object> eddystoneMap = new Dictionary<string, object>();
                //Eddystone total status quantity (1 byte)
                eddystoneMap.Add("Total_Status", (sbyte)msgContentArr[0]);
                msgContentArr = msgContentArr.Skip(1).Take(msgContentArr.Length - 1).ToArray();
                //mac (6 byte)
                byte[] macArr = msgContentArr.Skip(0).Take(6).ToArray();
                eddystoneMap.Add("Mac", CommonUtil.ByteToHexStr(macArr));
                msgContentArr = msgContentArr.Skip(6).Take(msgContentArr.Length - 6).ToArray();
                //RSSI (1 byte)
                eddystoneMap.Add("RSSI", (sbyte)msgContentArr[0]);
                msgContentArr = msgContentArr.Skip(1).Take(msgContentArr.Length - 1).ToArray();
                //Broadcast data
                List<string> broadcastList = new List<string>();
                while (msgContentArr.Length >= 31) {
                    byte[] broadcastArr = msgContentArr.Skip(0).Take(31).ToArray();
                    //Decoding broadcast data
                    broadcastList.Add(CommonUtil.ByteToHexStr(broadcastArr));
                    msgContentArr = msgContentArr.Skip(31).Take(msgContentArr.Length - 31).ToArray();
                }
                eddystoneMap.Add("Broadcast_Data", broadcastList);
                return JsonConvert.SerializeObject(eddystoneMap);
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 20240112 Sensor Log data
        /// </summary>
        /// <param name="msgContentArr"></param>
        /// <returns></returns>
        private static string parse54TransparentMessage(byte[] msgBodyBuf) {
            try
            {
                //status
                long status = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 0));
                //latitude
                double lat = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 4)) * 0.000001;
                //longitude
                double lon = CommonUtil.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 8)) * 0.000001;
                //Altitude, in meters
                int altitude = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 12));
                //speed
                double speed = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 14)) * 0.1;
                //direction
                int direction = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 16));
                //gps time
                DateTime gpsDateTime = CommonUtil.GetDataTime(msgBodyBuf.Skip(18).Take(6).ToArray());
                //Judge whether south latitude and west longitude
                if (CommonUtil.getBitValue(status, 2) == 1)
                {
                    lat = -lat;
                }
                if (CommonUtil.getBitValue(status, 3) == 1)
                {
                    lon = -lon;
                }
                //Positioning type
                int locationType = CommonUtil.getBitValue(status, 1);
                //ACC
                int acc = CommonUtil.getBitValue(status, 0);
                LocationData locationData = new LocationData();
                locationData.GpsTime = gpsDateTime.ToString("yyyy-MM-dd HH:mm:ss");
                locationData.Latitude = lat;
                locationData.Longitude = lon;
                locationData.LocationType = locationType;
                locationData.Speed = (int)speed;
                locationData.Direction = direction;
                locationData.Altitude = altitude;
                locationData.ACC = acc;
                if (msgBodyBuf.Length > 24)
                {
                    msgBodyBuf = msgBodyBuf.Skip(24).Take(msgBodyBuf.Length - 24).ToArray();
                    return parse54SensorLog(locationData, msgBodyBuf);
                }
                else
                {
                    return "";
                }
            }
            catch (Exception ex) {
                return "";
            }
        }

        /// <summary>
        /// parse 0x54 Sensor log
        /// </summary>
        /// <param name="locationData"></param>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        private static string parse54SensorLog(LocationData locationData, byte[] msgBodyBuf) {
            try
            {
                List<LocationData> locationDataList = new List<LocationData>();
                while (msgBodyBuf.Length > 7)
                {
                    LocationData location = new LocationData();
                    location.Latitude = locationData.Latitude;
                    location.Longitude = locationData.Longitude;
                    location.LocationType = locationData.LocationType;
                    location.Speed = locationData.Speed;
                    location.Direction = locationData.Direction;
                    location.Altitude = locationData.Altitude;
                    location.ACC = locationData.ACC;
                    int mask = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
                    msgBodyBuf = msgBodyBuf.Skip(2).Take(msgBodyBuf.Length - 2).ToArray();
                    //gps time
                    DateTime gpsDateTime = CommonUtil.GetDataTime(msgBodyBuf.Skip(0).Take(6).ToArray());
                    location.GpsTime = gpsDateTime.ToString("yyyy-MM-dd HH:mm:ss");
                    msgBodyBuf = msgBodyBuf.Skip(6).Take(msgBodyBuf.Length - 6).ToArray();
                    Dictionary<string, Object> extraInfo = new Dictionary<string, object>();
                    Dictionary<string, object> sensorInfo = new Dictionary<string, object>();
                    Dictionary<string, object> auxiliaryInfo = new Dictionary<string, object>();
                    if ((mask & 0x01) > 0)
                    {
                        //Illuminance
                        int aovx_light = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
                        msgBodyBuf = msgBodyBuf.Skip(2).Take(msgBodyBuf.Length - 2).ToArray();
                        sensorInfo.Add("Sensor_Light", aovx_light);
                    }
                    if ((mask & 0x02) > 0)
                    {
                        //temperature
                        double aovx_temperature = parseTemperature(CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0)));
                        msgBodyBuf = msgBodyBuf.Skip(2).Take(msgBodyBuf.Length - 2).ToArray();
                        sensorInfo.Add("Sensor_Temperature", aovx_temperature);
                        //humidity
                        int aovx_humidity = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
                        msgBodyBuf = msgBodyBuf.Skip(2).Take(msgBodyBuf.Length - 2).ToArray();
                        sensorInfo.Add("Sensor_Humidity", double.Parse((aovx_humidity * 0.1).ToString("0.0")));
                    }
                    if ((mask & 0x04) > 0)
                    {
                        //ext_temp
                        double ext_temp = parseTemperature(CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0)));
                        auxiliaryInfo.Add("Ext_Temp", ext_temp);
                        msgBodyBuf = msgBodyBuf.Skip(2).Take(msgBodyBuf.Length - 2).ToArray();
                    }
                    if ((mask & 0x08) > 0)
                    {
                        //Accelerometer
                        int x = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0));
                        int y = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 2));
                        int z = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 4));
                        x = x > 32768 ? (x - 65536) : x;
                        y = y > 32768 ? (y - 65536) : y;
                        z = z > 32768 ? (z - 65536) : z;
                        msgBodyBuf = msgBodyBuf.Skip(6).Take(msgBodyBuf.Length - 6).ToArray();
                        sensorInfo.Add("Sensor_Accelerometer", string.Format("x:{0},y:{1},z:{2}", x, y, z));
                    }
                    if ((mask & 0x10) > 0)
                    {
                        //Pressure
                        int pressure = CommonUtil.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 0)) * 100;
                        sensorInfo.Add("Pressure", pressure);
                        msgBodyBuf = msgBodyBuf.Skip(2).Take(msgBodyBuf.Length - 2).ToArray();
                    }
                    if (auxiliaryInfo.Count > 0)
                    {
                        extraInfo.Add("Auxiliary", auxiliaryInfo);
                    }
                    if (sensorInfo.Count > 0)
                    {
                        extraInfo.Add("Sensor", sensorInfo);
                    }
                    location.ExtraInfoMap = extraInfo;
                    locationDataList.Add(location);
                }
                return JsonConvert.SerializeObject(locationDataList);
            }
            catch (Exception ex)
            {
                return "";
            }
        }
    }
}
